\chapter{A Simple Example: An Address Book}
\chaptermark{Address Book Example}
\label{chap:simpleex}
% All figures in this chapter are available on the web in png format at:
%   http://www.usegantry.org/images/tenttut/{name}.png
% where {name} is the name of the eps file loaded here.

Most Gantry apps (and probably most web apps) are really database front ends.
This leads to a philosophy of web development: concentrate on the data model.
To have an example, consider my wife's address
book\index{address book}.  Suppose I want to migrate
this to a web app, so she can more easily back it up and stop lugging it
around.  (I apologize to readers intimate with the project docs, for
whom this is all starting to sound strikingly familiar.  There are novel
examples in this book.  See the `Contact Us' and `Job Ads' case studies in
Part II.)

The initial data model for an address
book\index{address book!data model}\index{data model!address book}
is pretty simple, with just
one table having a row for each person or family.  We'll make it slightly
more interesting later, by allowing birthdays.

\section{Take One: Name and number please.}

There are many ways to build a one table web app.  Even if we limit ourselves
to Gantry, there are still several approaches.  I'm looking for the easiest
one.\begin{footnote}
Since this book was written new developments have made an even easier approach
available.  See Bigtop::ScriptHelp::Style::KickStart for details.
\end{footnote}
Therefore, I'll start with
bigtop generation\index{bigtop!new app}:

\begin{verbatim}
bigtop --new AddressBook address
\end{verbatim}

\noindent
(You may abbreviate all bigtop command line option flags with their first
letter, as in \verb+bigtop -n ...+.)

This will create the app in a subdirectory of the current directory
called AddressBook.  If you perform the above and change into that directory,
you will see these things (you might also see app.db, more on that later):

\begin{verbatim}
app.cgi     Build.PL  docs  lib       MANIFEST.SKIP  t
app.server  Changes   html  MANIFEST  README
\end{verbatim}

Many of these are familiar to anyone who has built a module for CPAN:
lib, t, Changes, README, MANIFEST, MANIFEST.SKIP, and even Build.PL -- which
h2xs does not make, but seems to be taking over from Makefile.PL.

The other four are specific to Gantry and Bigtop:

\vspace{.2in}

\begin{center}
\begin{tabular}{l|l}
Name & Purpose \\
\hline
app.cgi    & A ready to use CGI script once the app is installed \\
app.server & A stand alone web server for immediate use          \\
docs       & Home for misc. files                                \\
html       & Home to templates and other web files               \\
\end{tabular}
\end{center}

\vspace{.2in}

If you have SQLite\index{SQL!SQLite!database creation}
installed -- and if
you don't you should -- you can
create a database and bring up the app:

\begin{verbatim}
sqlite app.db < docs/schema.sqlite
./app.server [ port ]
\end{verbatim}

In fact, if bigtop can find your sqlite executable, it will try to make
the database for you.  Either way it will print a few small paragraphs
of instructions on how to start your app whenever you run it in \verb+--new+
mode.

Note that the generated SQL in \verb+schema.sqlite+ is for version 3 of sqlite.
On many systems including Debian and Darwin the command is \verb+sqlite3+.
Using \verb+schema.sqlite+ with older versions of sqlite is doomed
to fail.

The files generated by bigtop (in new mode) expect the database to be named
app.db\index{app.db}.  They also think you'll prefer to start out using SQLite.
You can control the name of the database app.server uses, along with the
database engine DBD, user name, and password with command line flags.
See `Dealing with Databases' below for details.

By default app.server will start on port 8080, if you want a different
port, type the number on the command line.  When it starts, it will list
all the URLs it can serve on the screen.  All that remains is to
point your browser to one of those.

Of course, there are problems with this address book.  Its single table
has columns called ident and description.  We want better names for ourselves
and better labels for our users.  I can already hear Lisa asking, ``What's
ident?''  Answering, ``A person's name,'' is not going to work.

The easiest way to work on the app is to edit the bigtop file -- in either
a text editor or tentmaker.  tentmaker\index{tentmaker} is a browser delivered
app (which is really a Gantry app running in a stand alone server).
Using tentmaker is easy (presuming you installed its templates along with
Bigtop).  Simply type:

\begin{verbatim}
tentmaker docs/addressbook.bigtop
\end{verbatim}

It will try to start on port 8080.  Since it has the same default as
app.server, I usually run only one of them at a time.  If that port doesn't
suit you, supply a port\begin{footnote}
Note that you may spell out the flag as \verb+--port+.
\end{footnote}
of your choice:

\begin{verbatim}
tentmaker -p 8192 docs/addressbook.bigtop
\end{verbatim}


Keep in mind that tentmaker is a socket server\index{tentmaker!security},
so it is perfectly willing
to take orders from anyone who can contact it.  Some careful firewalling
is in order.  You might also want to create a limited rights user (like
you would for Apache) to run tentmaker.  Even if someone manages to contact
your tentmaker, they can do little harm beyond overwriting files with bigtop
source files (which is not too large a problem unless you run it as root,
which you shouldn't).

Once you start tentmaker, point your browser to the port you picked for it
and you should see something like Figure \ref{fig:tentopening}.  Note that
your browser needs to be somewhat standards compliant, like Firefox or
Safari (in particular tentmaker does not work with Internet Explorer).
There are four tabs\index{tentmaker!tabs} which let you describe your
app listed in Table \ref{tab:tenttabs1}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{tentopening}
\end{center}
\caption{The opening appearance of tentmaker\index{tentmaker!opening screen}.}
\label{fig:tentopening}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Tab Label & Allows you to specify... \\
\hline
Bigtop Config &
    the name of the app and a choice of \\ 
 &  engines to serve it \\

App Body &
    the meat of your app, i.e. your tables \\ 
 &  and controllers \\

Backends &
    the list of all things bigtop should \\
 &  make for you.  Use check boxes to    \\
 &  choose what you want it to do and    \\
 &  input boxes to configure each        \\
 &  backend's output. \\

App Level Statements &
    author names, their email addresses, \\
 &  project license, etc., all of these  \\
 &  have nice defaults \\ 

App Config &
    this configuration table has moved to \\
 &  the App Body tab \\
\end{tabular}
\end{center}
\caption{The five tabs of tentmaker (same as Table \ref{tab:tenttabs2}).}
\label{tab:tenttabs1}
\end{table}

We'll eventually visit all of the tabs in Chapter \ref{chap:tentref},
for now let's concentrate on making our address book work as my wife might
expect.  With that in mind the only thing of current interest on tentmaker's
opening page is the Save As button and the file name next to it.
Once we make our changes, we will return to this tab to press the button.

There are two issues we need to address: the columns in our table and
the database we are using.

To change the column names and add some new ones, click on the `App Body'
tab.  There you will see something similar to Figure \ref{fig:appbody}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{appbody}
\end{center}
\caption{The App Body tentmaker tab for the address book example.}
\label{fig:appbody}
\end{figure}

We need to change the table and to reflect our column
name preferences.  Start by scrolling down until you see the address
table block.  Then click
`edit'\index{table!edit in tentmaker}\index{tentmaker!table editing}
for it.
This will expand to show the statements and columns defined for the
table, as shown in Figure \ref{fig:tableedit1}.
You may click edit again, at any time, to collapse the edit box.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{tableedit}
\end{center}
\caption{Editing a table in tentmaker (same as Figure \ref{fig:tableedit2}).}
\label{fig:tableedit1}
\end{figure}

First, scroll down in the tabbed pane to the
Field Quick
Edit\index{tentmaker!Field Quick Edit}\index{Field Quick Edit in tentmaker}
table shown more clearly in Figure \ref{fig:quickedit}.
Our original bigtop generation gave us five
columns\index{table!default columns}\index{bigtop!default columns}:
id,\footnote{id does not appear in the Field Quick Edit box} ident,
description,
created, and modified.  The last two are dates in case we want to start
tracking changes.  At least that would give my wife some clue of
address quality.  For now, we'll just ignore those.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{quickedit}
\end{center}
\caption{A Quick Edit table in tentmaker.}
\label{fig:quickedit}
\end{figure}

That leaves the dreaded default columns ident and description.
Let's start by changing their names to `name' and `number.'  Just click
into the text fields under the `Column Name' label to do that.  To apply the
changes, click anywhere outside of the input box.  If you can't think
of a better place, feel free to click the apparently useful
`Apply Quick Edit'
button\index{tentmaker!Apply Quick Edit}.

This is a good time to add additional fields for address information.
Add these by entering their names into the
Create Field\index{tentmaker!Create Field}\index{Create Field in tentmaker}
box and pressing
the button.  My table has these: address, city, state, zip, and email.
Add any that make sense to you.  Note that you can add all of these
at once by typing their names, separated by spaces, into the Name(s)
box and clicking `Create.'

When tentmaker makes a new field\index{tentmaker!default field labels}
for you, it gives it a corresponding
label.  It does that by splitting the name at each underscore
and capitalizing the first letter of each resulting word.
The same thing happens when you change the name of a field, if the
old label was formed that way.  If any of those labels looks odd -- perhaps
you prefer `email' to `Email' -- change them by typing your choice
into the corresponding `Label' input box.

If the new field should store something more interesting than text, you'll
also need to change the SQL type for it in the
SQL Type\index{tentmaker!SQL types}\index{SQL!type in tentmaker}
column.
Note that there is no reason to change the type from
varchar\index{varchar}
if you need
a string, even if your database needs something more specific.  The bigtop
backend for your database will magically convert it into something sensible.
If you object to magic, supply the type of your choice.  But realize that
one of the joys of this development approach is the ease of switching
database engines, which will be lost if you use types
only your database understands.
Now save the bigtop file and regenerate:

\begin{verbatim}
bigtop docs/addressbook.bigtop all
\end{verbatim}

\subsection*{Dealing with Databases\index{database!engine in app.server}}

Before we restart our app.server, we need to address the database.
The one we used previously will not work, since the app now expects
different column names and more columns.

Since SQLite didn't support table alterations at the time of this writing
(at least not in a production version), we can't keep using the one we
-- or bigtop -- originally built.  This opens the subject of database
support and connection.

For now, we'll rely on app.server to handle this for us.  See Chapter
\ref{chap:deploy} for how to handle it with CGI/FastCGI or \verb+mod_perl+.

Bigtop supports three databases:
SQLite, PostgreSQL, and MySQL.  Its default generation assumes SQLite,
because it is so easy to work with during initial development.
But its defaults actually make the SQL needed to build the database in
PostgreSQL and MySQL as well.  All of the SQL commands are in the
docs subdirectory of the build directory in files called
schema.\emph{backend},
where \emph{backend} is the database engine name.

If you want to stick with SQLite -- which is the easiest route -- delete
the old app.db,\index{app.db!recreating}
make a new one, and restart app.server\index{app.server!command line flags}:

\begin{verbatim}
sqlite app.db < docs/schema.sqlite
./app.server
\end{verbatim}

For PostgreSQL\index{PostgreSQL}
this process goes like this (adjust the user names and
supply database passwords as needed):

\begin{verbatim}
createdb app.db -U postgres
psql app.db -U regular_user < docs/schema.postgres 
./app.server -d Pg -u regular_user -p password
\end{verbatim}

For MySQL\index{MySQL}
it goes like this (again, adjust the user names and supply
database passwords as needed):

\begin{verbatim}
mysqladmin create app_db -u root -p
mysql -u regular_user -p app_db < docs/schema.mysql
./app.server -d mysql -u regular_user -p password -n app_server
\end{verbatim}

Regardless of which database engine you use, you can change the name of
the database app.server will use with the -n flag (short for
--dbname\index{--dbname app.server flag}).

Of course, you could also edit app.server so it uses different defaults.
If you do that, remember to
uncheck\index{tentmaker!turn off app.server generation}
the `Build Server' box for the
CGI Gantry backend on the `Backends' tab in tentmaker.  Otherwise, whenever
you run bigtop, your changes will be overwritten.

\subsubsection*{Dealing with schema changes\index{data model!changes}}

As development proceeds, data model changes are all but inevitable.
That is really the point of bigtop and its tentmaker editor.  Those
tools help with all the code and schema changes.  But there is one
thing they can't do: alter your database.

Every time I get tool envy about automated schema alterations, my
colleagues talk me out of working on the problem.  They always assert
that they wouldn't trust a tool to make production database alterations
under any circumstances.  Until they change there minds, there probably
won't be a schema change component to bigtop.

But, there is one thing bigtop can do to lessen the pain of data model
changes during development.  You can include literal SQL in the bigtop
file which will go directly into the generated docs/schema.* files
(at present all of them always receive the same SQL).  There is also
a table level data statement.  You can enter as many of these
as you like for any table.  Each one generates an INSERT INTO statement
for its table.  Combining literal SQL with data statements you can
have a nice, fresh database -- full of all sorts of lovely test data --
simply by blowing away your old database and building a new one as shown
above.  These techniques are shown in Sections \ref{sec:billingbigtop}
and \ref{sec:authusers}.
There are also question/answer pairs about initial data in
Bigtop::Docs::Cookbook.  Look for, `How can I include initial data in a table?'
and `How do I put extra things into schema.*?'

\section{Interlude: Is this really
required\index{tentmaker!making fields optional}?}

To make further changes, we can revisit the bigtop file with tentmaker
or a text editor, save the result, and regenerate the app as shown above
(always being careful to alter or replace the database as needed).  For
example, upon running the new version, I remembered that by default, all
fields are required.  But, Lisa's poor little fingers may not want to type
in all the data for each contact in her book -- she might not even know
most of it for most people.  So, we want to use tentmaker to make the fields
optional on the add and edit form.

Stop the app.server script (if it's still running).  From the build directory,
restart tentmaker, again giving it the existing bigtop
file:\begin{footnote}Remember to provide \verb+--port=...+ if needed.
\end{footnote}

\begin{verbatim}
tentmaker docs/addressbook.bigtop
\end{verbatim}

Click on the `App Body' tab so we can mark fields as optional in the address
table.  Click on the `address' table's `edit' link.  Lisa wants address,
city, state, zip, phone, and email to be optional (that's right, only name
will be required).  So, we should check the Optional box for
all the fields except name in tentmaker.
We can also do this for all the fields by checking the Optional box in the
heading row.  Then, we can uncheck the ones we want to require, like the
name.

As a final touch, I think it would be a good idea to show the email address
next to the phone number on the main listing.  While still in tentmaker,
scroll down to the controller called Address and click `edit.'  You should
see something like Figure \ref{fig:controledit1}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{controledit}
\end{center}
\caption{Editing a controller in tentmaker (same as
Figure \ref{fig:controledit2}).}
\label{fig:controledit1}
\end{figure}

From there, look for the method called \verb+do_main+ and edit it as
shown in Figure \ref{fig:mainlistedit}.\begin{footnote}
Note that I trimmed the tentmaker screen shot to fit on the page.  Your
edit box will show a couple of additional documentation columns in the
HTML table.
\end{footnote}
Add `email' below `number' in a \verb+cols+ box.

Save the bigtop file.  Then stop tentmaker and
rebuild\index{tentmaker!regenerate app}\index{bigtop!regeneration} the app:

\begin{verbatim}
bigtop docs/addressbook.bigtop all
\end{verbatim}

\begin{figure}
\begin{center}
\includegraphics[width=4in]{mainlistedit}
\end{center}
\caption{Editing a main listing.}
\label{fig:mainlistedit}
\end{figure}

Since we didn't make changes to the database, we can restart the app
immediately.\footnote{Use whatever command line flags you used before.}

\begin{verbatim}
./app.server
\end{verbatim}

Note that the app.server always looks for your code in the
lib\index{app.server!lib directory}
subdirectory
of the build directory.  It never looks in blib/lib, so there is no
reason to run Build.PL at this point (unless you want to run the default
tests).

\section{Take Two: Should I send a card?}
\label{sec:asciiart}

Now, let's look at a more interesting exercise in that old address book.
On the back end paper, Lisa has scribbled some birth dates.
Perhaps including those dates in our present app will improve our on-time
arrival percentage for cards and gifts (then again, perhaps not).
It will certainly show off a few features of Gantry and Bigtop.

To add a table, we can ask tentmaker to
augment\index{tentmaker!augmenting}\index{-a, augment flag}
the existing bigtop file
during start up:

\begin{verbatim}
tentmaker -a docs/addressbook.bigtop 'bday->address'
\end{verbatim}

This not only adds the \verb+bday+ table, but gives it a foreign key
pointing to the
address table.  All we need to do from there is change the field names
of the new bday table to something more evocative and make sure they have
the proper `SQL Types.'

All the ASCII
art\index{ASCII art operators}\index{table!relationship operators}
operators and what they mean are shown in Table
\ref{tab:asciiart}.
You may use exactly the same \verb+-a+ and \verb+-n+ flags with both
bigtop and tentmaker.  But, always keep mind that using \verb+-n+ or
\verb+-a+ with bigtop will automatically build or rebuild the
application, while tentmaker never rebuilds.  Every time you
save changes in tentmaker, you need to run \verb+bigtop file.bigtop all+
for them to affect the application.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l|l}
Operator   & Name & Example & Meaning \\
\hline
\verb+->+\index{$->$@\verb+->+}  & many-to-one    & book\verb+->+author
           & book has a foreign \\
           & & & key to author \\
\verb+<-+\index{$<-$@\verb+<-+}  & one-to-many    & author\verb+<-+book
           & book has a foreign \\
           & & & key to author \\
\verb+-+\index{$-$@\verb+-+}   & one-to-one     & user\verb+-+extrainfo
           & user and extrainfo    \\
           & & & have foreign keys \\
           & & & to each other     \\
\verb+<->+\index{$<->$@\verb+<->+} & many-to-many   & fox\verb+<->+sock
           & fox and sock share \\
           & & & a many-to-many \\
           & & & relationship\\
\end{tabular}
\end{center}
\caption{ASCII art table relationship operators.}
\label{tab:asciiart}
\end{table}

New tables are created in the order they are listed, so \verb+->+ and
\verb+<-+ are synonyms except for the table creation order.
Note that while existing tables mentioned in ASCII art are not recreated,
they will receive new foreign keys or many-to-many relationships.

With tentmaker restarted and the new table in place,
edit the field names for the new
\verb+bday+\index{address book!bday table}\index{bday table in address book}
table, just as we did for
the address table, changing the names of the ident and
description fields.  
All that remains is to make the date
selectable\index{date selections}.
Change the SQL Type of
the birth day field -- whatever you called it -- to date.

After you regenerate the app, there should be a new navigation tab
labeled \verb+Bday+ (or some other phrase according to your table name).
Go to it, to start entering birth days.

\section*{Summary}

In this chapter we have seen how to use tentmaker to create a two table
web app for which we didn't have to write any code manually.  The next
chapter explains how to move this app into a \verb+mod_perl+ environment
with or without using Gantry::Conf to manage the configuration information.

Alternatively, now that we have seen how to use tentmaker to modify generated
apps, you are ready for a more thorough tour.  If you want to take it now,
go to Chapter \ref{chap:tentref}.
